package org.msb.accentis.gui.dialogs;

import static java.awt.GridBagConstraints.CENTER;
import static java.awt.GridBagConstraints.HORIZONTAL;
import static java.awt.GridBagConstraints.NONE;
import static java.awt.GridBagConstraints.SOUTHEAST;

import java.awt.Container;
import java.awt.Cursor;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;

import org.msb.accentis.data.DataManagerFactory;
import org.msb.accentis.gui.InsetsConstants;
import org.msb.accentis.gui.Resources;
import org.msb.accentis.gui.swing.ActionResourceDefinition;
import org.msb.accentis.gui.swing.MSBAction;

public class OpenDatabaseDialog {

	private JFileChooser fileChooser;

	private PasswordDialog passwordDialog;

	private Window parent;

	public OpenDatabaseDialog(Window owner) {
		parent = owner;
	}

	public void show() {
		JFileChooser fileChooser = getFileChooser();
		if (JFileChooser.APPROVE_OPTION == fileChooser.showOpenDialog(parent)) {
			File location = fileChooser.getSelectedFile();

			PasswordDialog dialog = getPasswordDialog();
			if (JFileChooser.APPROVE_OPTION == dialog.showPasswordDialog()) {
				char[] password = getPasswordDialog().getPassword();

				parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
				DataManagerFactory.getInstance().openDataManager(location.getAbsolutePath(), password);
				parent.setCursor(Cursor.getDefaultCursor());
			}
		}
	}

	private JFileChooser getFileChooser() {
		if (null == fileChooser)
			createFileChooser();

		return fileChooser;
	}

	private void createFileChooser() {
		fileChooser = new JFileChooser();
		fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		fileChooser.setDialogTitle(Resources.getInstance().getString("mainframe.opendialog.title"));
	}

	private PasswordDialog getPasswordDialog() {
		if (null == passwordDialog)
			createPasswordDialog();

		return passwordDialog;
	}

	private void createPasswordDialog() {
		passwordDialog = new PasswordDialog(parent);
	}

	public class PasswordDialog extends JDialog {

		private JPasswordField passwordField;

		private Action okAction;

		private Action cancelAction;

		private ActionListener actionListener;

		private int code;

		public PasswordDialog(Window owner) {
			super(owner, Resources.getInstance().getString("opendatabasedialog.passworddialog.title"), ModalityType.APPLICATION_MODAL);
		}

		@Override
		protected void dialogInit() {
			super.dialogInit();

			setContentPane(createContentPane());
			setLocationRelativeTo(getParent());
			pack();
		}

		private Container createContentPane() {
			JPanel contentPane = new JPanel(new GridBagLayout());
			contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

			contentPane.add(new JLabel(Resources.getInstance().getString("opendatabasedialog.password.caption")), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
					CENTER, NONE, InsetsConstants.ZERO_INSETS, 0, 0));
			contentPane.add(getPasswordField(), new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, CENTER, HORIZONTAL, InsetsConstants.FIVE_ON_LEFT_INSETS, 0, 0));

			JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 5, 0));
			buttonPanel.add(createDefaultButton(getOKAction()));
			buttonPanel.add(new JButton(getCancelAction()));

			contentPane.add(buttonPanel, new GridBagConstraints(0, 1, 2, 1, 0.0, 1.0, SOUTHEAST, NONE, InsetsConstants.FIVE_ON_TOP_INSETS, 0, 0));

			return contentPane;
		}
		
		private JButton createDefaultButton(Action action) {
			JButton button = new JButton(action);
			getRootPane().setDefaultButton(button);
			
			return button;
		}

		protected JPasswordField getPasswordField() {
			if (null == passwordField)
				createPasswordField();

			return passwordField;
		}

		private void createPasswordField() {
			passwordField = new JPasswordField(16);
		}

		protected Action getOKAction() {
			if (null == okAction)
				createOKAction();

			return okAction;
		}

		private void createOKAction() {
			okAction = new MSBAction(new ActionResourceDefinition(Resources.getInstance().getString("action.button.ok"), "ok"), getActionListener());
		}

		protected Action getCancelAction() {
			if (null == cancelAction)
				createCancelAction();

			return cancelAction;
		}

		private void createCancelAction() {
			cancelAction = new MSBAction(new ActionResourceDefinition(Resources.getInstance().getString("action.button.cancel"), "cancel"), getActionListener());
		}

		protected ActionListener getActionListener() {
			if (null == actionListener)
				actionListener = new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						String command = e.getActionCommand();
						assert null != command : "null action command encountered in OpenDatabaseDialog";

						if (command.equals("ok"))
							doOK();
						else if (command.equals("cancel"))
							doCancel();
					}
				};

			return actionListener;
		}

		private void doOK() {
			code = JFileChooser.APPROVE_OPTION;
			setVisible(false);
		}

		private void doCancel() {
			code = JFileChooser.CANCEL_OPTION;
			setVisible(false);
		}

		public int showPasswordDialog() {
			getPasswordField().setText(null);
			setVisible(true);

			return code;
		}

		public char[] getPassword() {
			return getPasswordField().getPassword();
		}
	}
}
